package com.huatech.support.shiro;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.SerializationUtils;

import com.alibaba.fastjson.JSONObject;
import com.huatech.support.redis.RedisUtil;

/**
 * 用户角色、权限缓存管理
 * @author lh@erongdu.com
 *
 */
public class RedisCacheManagerBak implements CacheManager {
	
	//@Resource RedisTemplate<String, Object> redisTemplate;
	private static final Logger LOGGER = LoggerFactory.getLogger(RedisCacheManagerBak.class);
	@Resource RedisUtil redisUtil;
	
	@Override
	public <K, V> Cache<K, V> getCache(String arg0) throws CacheException {
		return new RedisCache<K, V>();
	}
	
	class RedisCache<K, V> implements Cache<K, V>{

		private static final String CACHE_KEY = "redis-cache";
		
		@Override
		public void clear() throws CacheException {
			redisUtil.del(CACHE_KEY.getBytes());
		}
		
		private byte[] getKey(){
			return CACHE_KEY.getBytes();
		}
		
		private byte[] getField(K k){
			return SerializationUtils.serialize(k);
		}
		
		private String toString(Object obj){
			if(obj instanceof String){
				return obj.toString();
			}else{
				return JSONObject.toJSONString(obj);
			}
		}

		@SuppressWarnings("unchecked")
		@Override
		public V get(K k) throws CacheException {
			LOGGER.info("get field:{}", toString(k));
			byte[] val = redisUtil.hget(getKey(), getField(k));
			if(val != null){
				return (V)SerializationUtils.deserialize(val);
			}
			return null;
		}

		@SuppressWarnings("unchecked")
		@Override
		public Set<K> keys() {
			LOGGER.info("keys");
			Set<byte[]> keys = redisUtil.hkeys(getKey());
			Set<K> rs = new HashSet<>();
			if(keys == null || keys.size() == 0){
				return rs;
			}
			for (byte[] bs : keys) {
				rs.add((K)SerializationUtils.deserialize(bs));
			}
			return rs;
		}

		@Override
		public V put(K k, V v) throws CacheException {
			LOGGER.info("put field:{}, value:{}", toString(k), toString(v));
			byte[] val = SerializationUtils.serialize(v);
			redisUtil.hset(getKey(), getField(k), val);
			return v;
		}

		@Override
		public V remove(K k) throws CacheException {
			LOGGER.info("remove field:{}", toString(k));
			V v = get(k);
			redisUtil.hdel(getKey(), getField(k));
			return v;
		}

		@Override
		public int size() {
			int size = redisUtil.hlen(getKey()).intValue();
			LOGGER.info("size:{}", size);
			return size;
		}

		@SuppressWarnings("unchecked")
		@Override
		public Collection<V> values() {
			LOGGER.info("values");
			List<byte[]> list = redisUtil.hvals(getKey());
			List<V> rs = new ArrayList<>();
			if(list == null || list.size() == 0){
				return rs;
			}
			for (byte[] bs : list) {
				rs.add((V)SerializationUtils.deserialize(bs));
			}
			return rs;
			
		}
		
		public String getCacheKey() {
			return "RedisCache";
		}
		
	}

}
